package com.panfeng.xcloud.gateway.filters;

import com.alibaba.fastjson.JSONObject;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.panfeng.xcloud.common.core.enums.ResponseStatusEnum;
import com.panfeng.xcloud.common.core.web.vo.ResponseVO;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.MessageFormat;

/**
 * 错误处理ZuulFilter过滤器
 *
 * @author xiaobo
 * @date 2018-03-15
 */
@Component
public class ErrorFilter extends ZuulFilter {

	private static final Logger logger = LoggerFactory.getLogger(ErrorFilter.class);

	@Value("${server.port}")
	private Integer serverPort;

	@Override
	public String filterType() {
		return FilterConstants.ERROR_TYPE;
	}

	@Override
	public int filterOrder() {
		return 10;
	}

	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public Object run() {
		RequestContext ctx = RequestContext.getCurrentContext();
		HttpServletRequest request = ctx.getRequest();
		Throwable throwable = ctx.getThrowable();
		logger.error(">>> 当前zuul出现内部异常，异常状态码statusCode：{} 异常信息exception：{} <<<", HttpServletResponse.SC_INTERNAL_SERVER_ERROR,throwable.getCause().getMessage());
		try {
			ResponseVO<String> responseVO = new ResponseVO<String>();
			responseVO.setCode(ResponseStatusEnum.INTERNAL_ERROR.getCode());
			String message = MessageFormat.format(
					ResponseStatusEnum.INTERNAL_ERROR.getMessage(),throwable.getCause().getMessage());
			responseVO.setMessage(message);
			String errorResponse = JSONObject.toJSONString(responseVO);
			logger.info("异常信息:{}", errorResponse);
			responseHandler(ctx, errorResponse);
			return null;
		} catch (IOException e) {
			logger.error("exception message is: {}",ExceptionUtils.getStackTrace(e));
			return null;
		}
	}

	/**
	 * 返回逻辑统一处理
	 *
	 * @param ctx
	 * @param errorResponse
	 * @throws IOException
	 */
	private void responseHandler(RequestContext ctx,
			String errorResponse) throws IOException {
		ctx.setSendZuulResponse(false);
		HttpServletResponse httpResponse = ctx.getResponse();
		httpResponse.setCharacterEncoding("UTF-8");
		httpResponse.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
		httpResponse.setStatus(HttpServletResponse.SC_OK);
		httpResponse.getWriter().write(errorResponse);
		ctx.setResponse(httpResponse);
	}

}
